package com.binguo.api.baidu;


import com.binguo.api.baidu.model.*;
import com.binguo.api.businessmodel.ProductImgDetailModel;
import com.binguo.api.businessmodel.ProductImgModel;

import com.binguo.api.huawei.imagesearch.model.RecResult;
import com.binguo.api.imgrec.ImgRecResult;
import com.binguo.api.imgrec.Results;

import com.binguo.api.response.product.ProductRecResultDetailVONewWithLocation;
import com.binguo.api.response.product.ProductRecResultVONewWithLocation;
import com.binguo.api.schedule.DataLoadService;
import com.binguo.common.paymodel.ThreadManager;
import com.binguo.common.util.JsonUtil;
import com.binguo.model.mapper.LogProductRecMapper;
import com.binguo.model.model.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.stream.Collectors;


@Service
public class BaiduRecUtilWithPallet {

    private static Logger logger = LoggerFactory.getLogger(BaiduRecUtilWithPallet.class);

    @Autowired
    private BaiduRecUtil baiduRecUtil;



    @Resource
    private LogProductRecMapper logProductRecMapper;

    /**
     * 餐盘格子识别
     * @param shopId
     * @param fileBase64Content
     * @param filename
     * @param outputFilepath
     * @param uuidFileName
     * @param imgUrl
     * @param sourceImgOnInternet
     * @param branchId
     * @param recType
     * @param imgWidth
     * @return
     * @throws Exception
     */
    public ProductRecResultVONewWithLocation searchWithPalletCell(Integer shopId, String fileBase64Content,
                                                                  String filename, String outputFilepath,
                                                                  String uuidFileName,
                                                                  String imgUrl, String sourceImgOnInternet, Integer branchId, Integer recType,
                                                                  Integer imgWidth
    ) throws Exception {

        Date date = Calendar.getInstance().getTime();
        long startTime = date.getTime();
        logger.info("开始识别:" + startTime);

        List<ProductYpRef> productYpRefList = null;
        if (DataLoadService.shopYpProductListMap != null) {
            productYpRefList = DataLoadService.shopYpProductListMap.get(shopId);
        }

        String token;
        boolean useMasterDb = false;

        int width = 30;
        if (imgWidth != null && imgWidth > 1000) {
            width = 60;
        }

        if (recType != null && recType.equals(1)) {
            token = baiduRecUtil.getBaiduToken(shopId, branchId);
            useMasterDb = true;
        }else {
//            if(DataLoadService.shopBaiduUrlCurListMap.get(shopId) != null){
//                token = baiduRecUtil.getBaiduTokenCur(shopId, branchId);
//                if (token == null) {
//                    token = baiduRecUtil.getBaiduToken(shopId, branchId);
//                    useMasterDb = true;
//                }
//            }else {
                token = baiduRecUtil.getBaiduToken(shopId, branchId);
//            }
        }

        String tempToken = token;


        RecResult huaRecResult = null;


        long localrecStart = System.currentTimeMillis();

        Map<String, String> param = new HashMap<>();
        param.put("shopId", shopId + "");
        param.put("imgUrl", sourceImgOnInternet);
        String jsonParam = JsonUtil.toJson(param);

        HttpEntity entity = new HttpEntity<>(jsonParam, baiduRecUtil.DEFAULT_JSON_HEADER_UTF8);

        String url = "http://180.76.105.132:8099/sendMsg9006";
        if (DataLoadService.shopBowlRecIpMap != null && DataLoadService.shopBowlRecIpMap.containsKey(shopId)) {
            url = DataLoadService.shopBowlRecIpMap.get(shopId);
        }

        ResponseEntity<String> recImgResult = new RestTemplate().postForEntity(url, entity, String.class);

        String localRecResultStr;
        try {
            String resultStr = recImgResult.getBody();
            localRecResultStr = resultStr;

            System.out.println(resultStr);
            logger.info("local识别结果：{}", resultStr);
            if (resultStr == null) {
                logger.info("本地模型识别无结果=");
                return null;
            }
            resultStr = resultStr.substring(resultStr.indexOf("results")-2);
            ImgRecResult resResult = JsonUtil.parse(resultStr, ImgRecResult.class);


            System.out.println(resResult.getNumber());

            if (resResult.getNumber() > 0) {

                huaRecResult = new RecResult();
                huaRecResult.setDetectionBoxes(new ArrayList<>());
                huaRecResult.setDetectionClasses(new ArrayList<>());
                huaRecResult.setDetectionScores(new ArrayList<>());

                for (Results res : resResult.getResults()) {
                    int x1 = res.getLocation().getLeft();
                    int y1 = res.getLocation().getTop();

                    int x2 = res.getLocation().getLeft() + res.getLocation().getWidth();
                    int y2 = res.getLocation().getTop() + res.getLocation().getHeight();


                    List<Double> location = new ArrayList<>();
                    location.add(Double.valueOf(y1));
                    location.add(Double.valueOf(x1));
                    location.add(Double.valueOf(y2));
                    location.add(Double.valueOf(x2));

                    huaRecResult.getDetectionBoxes().add(location);
                    huaRecResult.getDetectionScores().add(res.getScore());
                    huaRecResult.getDetectionClasses().add(res.getName());
                }


                long endTime = System.currentTimeMillis();
                logger.info("本地模型识别结果=" + JsonUtil.toJson(huaRecResult));
                logger.info("本地模型识别完成=" + endTime + ",huawei rec intelval=" + (endTime - localrecStart));


            }else {
                long endTime = System.currentTimeMillis();
                logger.info("本地模型识别无结果");
                logger.info("本地模型识别完成=" + endTime + ",huawei rec intelval=" + (endTime - localrecStart));
                return null;
            }
        } catch (IOException e) {
            e.printStackTrace();
            logger.info("本地模型识别错误：{}", e.getMessage());
            return null;
        }

        long errorExistStart = System.currentTimeMillis();


        ProductImgModel productImgModel = new ProductImgModel();
        productImgModel.setProductOrderNo(uuidFileName);
        productImgModel.setShopId(shopId);
        productImgModel.setSourceFilename(filename);
        productImgModel.setUuidFileName(uuidFileName);
        productImgModel.setImgUrl(imgUrl);
        productImgModel.setCurIpAddress(baiduRecUtil.ipAddress);
        productImgModel.setSourceImgOnInternet(sourceImgOnInternet);
        productImgModel.setItemList(new ArrayList<>());

        List<ImgTag> imgTagList = new ArrayList<>();

        ProductRecResultVONewWithLocation productRecResultVO = new ProductRecResultVONewWithLocation();
        productRecResultVO.setProductList(new ArrayList<>());
        productRecResultVO.setTotalFee(0l);
        productRecResultVO.setRealFee(0l);
        if (huaRecResult != null) {
            int index = 0;
            int seq = 1;


            List<Result> searchResultList = new ArrayList<>();

            for (int i=0; i < huaRecResult.getDetectionClasses().size(); i++) {

                double score = huaRecResult.getDetectionScores().get(i);

                if (score > 0.5) {
//                if (score > DataLoadService.huaweiScore) {
                    List<Double> boxes = huaRecResult.getDetectionBoxes().get(i);

                    if (boxes.get(0) < 10 && boxes.get(1) < 10) {
                        continue;
                    }

                    int y1 = boxes.get(0).intValue();
                    int x1 = boxes.get(1).intValue();

                    int y2 = boxes.get(2).intValue();
                    int x2 = boxes.get(3).intValue();


                    Result temp = new Result();
                    temp.setLocation(new Location());
                    temp.getLocation().setLeft(x1);
                    temp.getLocation().setTop(y1);
                    if (x2 > x1) {
                        temp.getLocation().setWidth(x2 - x1);
                    } else {
                        temp.getLocation().setWidth(x1 - x2);
                    }
                    if (y2 > y1) {
                        temp.getLocation().setHeight(y2 - y1);
                    } else {
                        temp.getLocation().setHeight(y1 - y2);
                    }

                    temp.setDishes(new ArrayList<>());
                    Dishes dishes = new Dishes();
                    dishes.setBrief(huaRecResult.getDetectionClasses().get(i));
                    dishes.setScore(score);
                    temp.getDishes().add(dishes);

                    searchResultList.add(temp);

                }
            }

            List<Result> needRemovedList = null;

            for (Result temp : searchResultList) {
                int x1 = temp.getLocation().getLeft();
                int y1 = temp.getLocation().getTop();

                int x2 = temp.getLocation().getLeft() + temp.getLocation().getWidth();
                int y2 = temp.getLocation().getTop() + temp.getLocation().getHeight();

                //右上角坐标
                int y11 = y1;
                int x11 = x2;

                for (Result compare : searchResultList) {
                    int x3 = compare.getLocation().getLeft();
                    int y3 = compare.getLocation().getTop();

                    int x4 = compare.getLocation().getLeft() + compare.getLocation().getWidth();
                    int y4 = compare.getLocation().getTop() + compare.getLocation().getHeight();

                    //右上角坐标
                    int y22 = y3;
                    int x22 = x4;

                    if (x1 < x3 && y1 < y3
                            && x2 > x4 && y2 > y4
                            ) {
                        logger.info("检测有图片包含: top=" + temp.getLocation().getTop());
                        if (needRemovedList == null) {
                            needRemovedList = new ArrayList<>();
                        }
                        needRemovedList.add(temp);
                    }

                    if (      ((x1 < (x3 + width) && x1 > (x3 - width))
                            && (y1 < (y3 + width) && y1 > (y3 - width)))

                            ||

                            ((x2 < (x4 + width) && x2 > (x4 - width))
                                    && (y2 < (y4 + width) && y2 > (y4 - width)))

                            ||

                            ((x11 < (x22 + width) && x11 > (x22 - width))
                                    && (y11 < (y22 + width) && y11 > (y22 - width)))


                            ){
                        if (x1 == x3 && y1 == y3 && x2 == x4) {
                            continue;
                        }

                        logger.info("检测附近有图片包含: top=" + temp.getLocation().getTop());
                        if (needRemovedList == null) {
                            needRemovedList = new ArrayList<>();
                        }

                        if (temp.getDishes().get(0).getScore() > compare.getDishes().get(0).getScore()) {
                            needRemovedList.add(compare);
                        }
                    }
                }
            }


            List<Future<RecResult>> recFutureList = new ArrayList<>();

            Map<String, ProductYpRef> searchCodeProductMap = null;
            if (productYpRefList != null && productYpRefList.size() > 0) {
                searchCodeProductMap =
                        productYpRefList.stream().collect(Collectors.toMap(ProductYpRef::getSearchCode, p->p));
            }

            for (Result temp : searchResultList) {
                boolean remove = false;
                if (needRemovedList != null) {
                    for (Result badResult : needRemovedList) {
                        if (badResult.getLocation().getTop() == temp.getLocation().getTop()
                                && badResult.getLocation().getWidth() == temp.getLocation().getWidth()
                                && badResult.getLocation().getHeight() == temp.getLocation().getHeight()
                                && badResult.getLocation().getLeft() == temp.getLocation().getLeft()
                                ) {
                            remove = true;
                            break;
                        }
                    }
                }

                if (remove) {
                    continue;
                }


                if (searchCodeProductMap != null && searchCodeProductMap.containsKey(temp.getDishes().get(0).getBrief())) {
                    ProductYpRef productYpRef = searchCodeProductMap.get(temp.getDishes().get(0).getBrief());

                    Product product = DataLoadService.productMap.get(productYpRef.getProductId());

                    String label = product.getName();

                    int x1 = temp.getLocation().getLeft();
                    int y1 = temp.getLocation().getTop();

                    int x2 = temp.getLocation().getLeft() + temp.getLocation().getWidth();
                    int y2 = temp.getLocation().getTop() + temp.getLocation().getHeight();

                    ImgTag imgTag = new ImgTag();
                    imgTag.setX1(x1);
                    imgTag.setY1(y1);
                    imgTag.setX2(x2);
                    imgTag.setY2(y2);
                    imgTag.setLabel(label);
                    imgTag.setScore(1);
                    imgTagList.add(imgTag);

                    /**
                     * save ProductImgDetailModel
                     */
                    ProductImgDetailModel productImgDetailModel = new ProductImgDetailModel();
                    productImgDetailModel.setProductName(product.getName());
                    productImgDetailModel.setProductId(product.getId());
                    productImgDetailModel.setSeq(seq);
                    productImgDetailModel.setLeft(x1);
                    productImgDetailModel.setTop(y1);
                    productImgDetailModel.setWidth(temp.getLocation().getWidth());
                    productImgDetailModel.setHeight(temp.getLocation().getHeight());
                    productImgDetailModel.setScore(100);
                    productImgModel.getItemList().add(productImgDetailModel);
                    ///----end

                    ProductRecResultDetailVONewWithLocation productRecResultDetailVO
                            = new ProductRecResultDetailVONewWithLocation();

                    productRecResultDetailVO.setX1(x1);
                    productRecResultDetailVO.setX2(x2);
                    productRecResultDetailVO.setY1(y1);
                    productRecResultDetailVO.setY2(y2);

                    productRecResultDetailVO.setProductName(product.getName());
                    productRecResultDetailVO.setProductId(product.getId());
                    productRecResultDetailVO.setProductPrice(product.getPrice());
                    productRecResultDetailVO.setItemCount(1);
                    productRecResultDetailVO.setSeq(seq);

                    productRecResultVO.getProductList().add(productRecResultDetailVO);
                    productRecResultVO.setTotalFee(productRecResultVO.getTotalFee().longValue()
                            + product.getPrice().longValue());

                }else {

                    //针对框出来不识别的情况
                    logger.info("======框出识别:{}, {}, {}, {}", temp.getLocation().getTop(),
                            temp.getLocation().getLeft(), temp.getLocation().getWidth(), temp.getLocation().getHeight());


                    Integer tempSeq = seq;
                    Integer tempIndex = index;

                    ProductRecResultVONewWithLocation tempProductRecResultVO = productRecResultVO;
                    Future<RecResult> localRecFuture = ThreadManager.executorService.submit((Callable) () ->
                    {
                        long reRecStart = System.currentTimeMillis();
                        baiduRecUtil.handleNotRecImg(filename, shopId, uuidFileName,
                                temp, tempProductRecResultVO, tempSeq,
                                productImgModel, imgTagList, branchId, tempIndex, tempToken, recType);
                        long reRecEnd = System.currentTimeMillis();
                        logger.info("======框出后识别时间:{}, tempIndex:{}", reRecEnd - reRecStart, tempIndex);
                        return null;
                    });

                    recFutureList.add(localRecFuture);
                }




                index++;

                seq++;
            }

            for (Future<RecResult> recResultFuture : recFutureList) {
                recResultFuture.get();
            }
            long errorExistEnd = System.currentTimeMillis();

            logger.info("======框出重新识别时间:{}", errorExistEnd - errorExistStart);


        }

        try {


                List<Result> searchResultList = null;

                if ((searchResultList != null && searchResultList.size() > 0)
                        || huaRecResult != null
                        ) {




                    int seq = 1;
                    long totalFee = 0;
                    for(ProductRecResultDetailVONewWithLocation p : productRecResultVO.getProductList()){
                        p.setSeq(seq);
                        totalFee += p.getProductPrice();

                        for (ImgTag imgTag : imgTagList) {
                            if (p.getX1() == imgTag.getX1()
                                    && p.getX2() == imgTag.getX2()
                                    && p.getY2() == imgTag.getY2()
                                    && p.getY1() == imgTag.getY1()
                                    ) {
                                imgTag.setLabel(seq + "、" + imgTag.getLabel());
                            }
                        }
                        seq++;
                    }
                    productRecResultVO.setRealFee(totalFee);
                    productRecResultVO.setTotalFee(totalFee);
                    productRecResultVO.setProductCount(productRecResultVO.getProductList().size());

                    ThreadManager.executorService.submit(() -> {
                        try {
                            if (productImgModel.getItemList() != null && productImgModel.getItemList().size() > 0) {
                                for (ProductImgDetailModel productImgDetailModel: productImgModel.getItemList()) {

                                    int modelTop = productImgDetailModel.getTop();
                                    int modelHeight = productImgDetailModel.getHeight();
                                    int modelLeft = productImgDetailModel.getLeft();
                                    int modelWidth = productImgDetailModel.getWidth();
                                    for (ImgTag imgTag : imgTagList) {
                                        if (modelLeft == imgTag.getX1()
                                                && modelTop == imgTag.getY1()
                                                ) {
                                            Integer modelSeq = Integer.valueOf(imgTag.getLabel().split("、")[0]);
                                            productImgDetailModel.setSeq(modelSeq);
                                        }
                                    }

                                }
                            }

                            baiduRecUtil.setKey(productImgModel.getProductOrderNo(), productImgModel, 60 * 60 * 1000);
                            ProductImgJsonInfo productImgJsonInfo = new ProductImgJsonInfo();
                            productImgJsonInfo.setProductContent(JsonUtil.toJson(productImgModel));
                            productImgJsonInfo.setProductOrderNo(productImgModel.getProductOrderNo());

                            baiduRecUtil.productImgJsonInfoMapper.insert(productImgJsonInfo);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    });
                }

                if (productRecResultVO == null) {
                    return null;
                }

                String imgJson = JsonUtil.toJson(imgTagList);

                logger.info("imgJson==" + imgJson);
                String temp = java.util.Base64.getEncoder().encodeToString(imgJson.getBytes());
                logger.info(temp);

                imgJson = URLEncoder.encode(temp);
                logger.info(imgJson);

                long endTime2 = System.currentTimeMillis();
                logger.info("endTime3=" + endTime2 + ", intelval=" + (endTime2 - startTime));

                String tempOutputFilepath = outputFilepath.replaceAll("/usr/local/nginx/html", "/data/html");
                String tempFilename = filename.replaceAll("/usr/local/nginx/html", "/data/html");

                String drwaImgParam = "outputFilepath=" + tempOutputFilepath + "&filename=" + tempFilename + "&image=" + imgJson;

                HttpEntity drawEntity = new HttpEntity<>(drwaImgParam, baiduRecUtil.DEFAULT_JSON_HEADER);

                ResponseEntity<String> drwaImgResult = baiduRecUtil.restTemplate.postForEntity("http://"+baiduRecUtil.recIp+":8082/hello2", drawEntity, String.class);

                logger.info(drwaImgResult.getBody());


                long endTime3 = System.currentTimeMillis();
                logger.info("endTime4=" + endTime3 + ", intelval=" + (endTime3 - endTime2));

                if ("ok".equals(drwaImgResult.getBody())) {

                    ThreadManager.executorService.submit(() -> {
                        LogProductRec logProductRec = new LogProductRec();
                        logProductRec.setFilepath(filename);
                        logProductRec.setOutputFilepath(outputFilepath);
                        logProductRec.setCreateTime(date);
                        logProductRec.setShopId(shopId);
                        logProductRec.setImgSrcNetUrl(sourceImgOnInternet);
                        logProductRec.setRecResult(null);
                        logProductRec.setImgResultNetUrl(imgUrl);
                        logProductRecMapper.insert(logProductRec);
                    });

                    ShopPackageDiscount shopPackageDiscount = baiduRecUtil.checkProductPackage(shopId, productRecResultVO);

                    if (shopPackageDiscount != null) {
                        productRecResultVO.setRealFee(shopPackageDiscount.getPrice());
                        productRecResultVO.setMealSetName(shopPackageDiscount.getName());
                        productRecResultVO.setMealSetId(shopPackageDiscount.getId());
                    }

                    return productRecResultVO;
                }


        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }





}
